;;数据抽象的方法学，将使用和表示分离开
;;这也是：过程也是对象的一种体现，也可以给它们命名

(define make-vector cons)
;等价于
(define (make-vector x y)
  (cons x y))

(define xcor car)
(define ycor cdr)
 
;;closure
 
(cons 1
      (cons 2
            (cons 3
                  (cons 4 nil))))
;;这是上面形式的语法糖
(list 1 2 3 4)
 
;;用递归的方式，处理表中的剩余元素，即表的cdr部分
;;然后用cons将该部分的结果，与经过处理后的表的第一个元素连接在一起

;;cdr-ing down a list
(define (scale-list s l)
  (if (null? l)
      nil
      (cons (* (car l) s) ;;first element of scaled list
            (scale-list s (cdr l))))) ;;rest of scaled list
 
(define (map p l)
  (if (null? l)
      nil
      (cons (p (car l)) ;;;apply p to first element
            (map p (cdr l))))) ;;;map down the rest of the list

(define (scale-list s l)
  (map (lambda (item)
         (* item s))
       l))
 
;;;开始使用map进行思考，即：对表中的每个元素进行一定操作，而不关心控制流程
 
(define (for-each proc list)
  (cond ((null? list) "done")
        (else (proc (car list)) ;;;do it to the first element
              (for-each proc (cdr list))))) ;;;do it to the rest of the list
 

;;;画图程序
;;;the primitive is only the picture
 
(beside g
        (above empty g 0.5)
        0.5)
 
(define p
  (beside g
          (rot-180 (flip g))
          0.5))
 
(define q
  (above p (flip p) 0.5))
 
;;为什么可以是复杂度快速增加
;;the answer is the closure property
;;当我将两个图像做beside操作后，得到的也是图像，
;;我可以继续执行rotate flip或者above操作，在这种组合方法下，图像的世界是封闭的
 
;;pair可以是数字的pair，也可以是数字和pair的pair，也可以是pair和pair的pair，所以pair是closure的
;;而有些语言，只能创建基本类型的数组，不能创建数组的数组，所以就不是closure的
 
;;矩形由三部分组成，原点origin，水平向量horiz，垂直向量vert
 
;;关键是，使用过程来表示图像，使其自动的具有闭包性质
 
;;;矩形的构造函数和选择函数，
;;;假设已经有了这些矩形了，也就是：只知道有这四个函数，具体实现由别人实现
;;;make-rect
;;;horiz
;;;vert
;;;origin
 
 
;;;(x, y) ---> origin + x*horiz + y*vert
;;;rectangular矩形   vector向量
;;;对矩形做变换，返回一个以点为参数的过程
(define (coord-map rect)
  (lambda (point)
    (+vect
     (+vect (scale (xcor point) (horiz rect)) ;;将点的x坐标缩放
            (scale (ycor point) (vert rect))) ;;将点的y坐标缩放
     (origin rect))))
 
;;;constructing primitive pictures from lists of segments
;;;返回一个以矩形为参数的过程，即：构建在矩形之上
;;;现在有了矩形，有了矩形的变换函数，然后就可以在这些不同的矩形中画图了
(define (make-picture seglist)
  (lambda (rect)
    (for-each
     (lambda (s)
       (drawline
        ((coord-map rect) (seg-start s))
        ((coord-map rect) (seg-end s))))
       seglist)))
 
;;;(define R (make-rect ... ))
;;;(define G (make-picture ... ))
;;;(G R)就可以实现在R这个矩形内画图
 
 
;;;在矩形内画图make-picture
;;;======================
;;;矩形变换函数coord-map
;;;======================
;;;    矩形
 
 
;;;有了矩形，矩形变换函数，(在矩形内)画图，现在就可以将不同的图像组合了
(define (beside p1 p2 a)
  (lambda (rect)
    (p1 (make-rect (origin rect)
                   (scale a (horiz rect))
                   (vert rect)))
    (p2 (make-rect (+vect (origin rect)
                          (scale a (horiz rect)))
                   (scale (- 1 a) (horiz rect))
                   (vert rect)))))
 
(define (above p1 p2 a)
  ... )
 
(define (rotate90 pict)
  (lambda (rect)
    (pict (make-rect (+vect (origin rect)
                            (horiz rect))
                     (vert rect)
                     (scale -1 (horiz rect))))))
 
(define (right-push p n a)
  (if (= n 0)
      p
      (beside p (right-push p (-n 1) a) a)))
 
(define (above-push p n a)
  ... )
 
 
;;;图像组合函数above，beside，rotate90，right-push等
;;;==============================================
;;;在矩形内画图make-picture
;;;==============================================
;;;矩形变换函数coord-map
;;;==============================================
;;;    矩形
 
 
;;;一般性的push，也就是使用高阶过程进行抽象
;;;参数为不同的组合方式，right，above，corner等
(define (push comb)
  (lambda (pict n a)
    ((repeated
      (lambda (x)
        (comb pict x a))
      n);;;返回一个picture为参数的过程
     pict)))
 
 
;;;图像组合函数above,beside,rotate90,right-push等
;;;==============================================
;;;一般图像组合函数push
;;;==============================================
;;;在矩形内画图make-picture
;;;==============================================
;;;矩形变换函数coord-map
;;;==============================================
;;;    矩形
 
     
;;层次关系：
;;;beside只接受图像p，不管这个图像p是什么
;;;图像p接受一个矩形，就自动画图
;;;beside并不关心图像是如何绘制的
 
;;we've implemented the means of combination themselves as procedures
 
(define (right-push p n a)
  (if (= n 0)
      p
      (beside p (right-push p (-n 1) a) a)))
 
 
;;将通用方法抽象成高阶过程
 
 
(define (push comb)
  (lambda (pict n a)
    ((repeated
      (lambda (p)
        (comb pict p a))
      n)
     pict))) ;;;将repeated的结果应用在pict上
 
 
;;;有了该一般性的push，reght-push就可以定义为以下形式：
(define right-push (push beside))
 
;;;在一个语言中嵌入另一个语言
 
 
;;;language of schemes of combination:
;;;push（用一个缩放因子，重复的做一件事）等
;;;===========================
;;;language of geometric（几何的） positions：
;;;above，beside，right-push，rotate等
;;;===========================
;;;language of primitive picts
